package com.yonyou.pmclouds.statistic.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.businessobject.util.SortListUtil;
import com.yonyou.pmclouds.outter.enterprise.EnterpriseInfoQuery;
import com.yonyou.pmclouds.outter.user.UserInfoQuery;
import com.yonyou.pmclouds.problemlog.entity.ProblemLogBillStatus;
import com.yonyou.pmclouds.problemlog.entity.ProblemLogVO;
import com.yonyou.pmclouds.statistic.entity.ProblemReasonPercentageVO;
import com.yonyou.pmclouds.statistic.entity.ProblemReportVO;
import com.yonyou.pmclouds.statistic.rmiitf.ProblemReasonAnalyseRemoteService;
import com.yonyou.pmclouds.team.entity.TeamEnterpriseVO;
import com.yonyou.pmclouds.team.entity.TeamMemberVO;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/problemReason/statistical")
public class ProblemReasonStatisticalController {

    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private ProblemReasonAnalyseRemoteService query;

    @Autowired
    private EnterpriseInfoQuery enterpriseInfoQuery;
    @Autowired
    private UserInfoQuery userInfoQuery;

    /**
     * 统计分析问题原因统计
     *
     * @param tenantId   租户ID
     * @param filterCode threeMonth（近三个月）、halfYear（近半年）、aYear（近一年）
     * @return 问题原因百分比VO
     */
    @GetMapping("/percentage")
    public List<ProblemReasonPercentageVO> queryProblemReasonPercentage(@RequestParam("tenantId") String tenantId,
                                                                        @RequestParam("filterCode") String filterCode,
                                                                        @RequestParam(name = "orgId",required = false) String orgId)
            throws BusinessException {

        return query.queryProblemReasonCount(tenantId, filterCode,orgId);
    }

    /**
     * 统计未关闭问题记录，已施工单位进行分组
     *
     * @param tenantId 租户ID
     */
    @GetMapping("/overdueCount")
    public ProblemReasonPercentageVO[] queryOverdueCount(@RequestParam("tenantId") String tenantId, @RequestParam("orgId") String orgId)
            throws BusinessException {
        // FIXME 问题记录过多的时候，可能会导致oom
        // 查询未关闭的所有问题记录
        List<ProblemLogVO> problemLogVOList = query.queryOverdueCount(tenantId, ProblemLogBillStatus.STATUS_END, orgId);
        if (problemLogVOList == null || problemLogVOList.size() <= 0) {
            return new ProblemReasonPercentageVO[0];
        }
        Set<String> rectificationerIdSet = new HashSet<>();
        for (ProblemLogVO problemLogVO : problemLogVOList) {
            rectificationerIdSet.add(problemLogVO.getPk_rectificationer());
        }
        // 通过整改人主键在项目团队中找出对应的企业
        TeamMemberVO[] teamMemberVOS = query.queryTeamMemberById(rectificationerIdSet.toArray(new String[0]));
        Map<String, String> userIdMap = new HashMap<>();
        Map<String, String> userAndPkEntMap = new HashMap<>();
        if (ArrayUtils.isNotEmpty(teamMemberVOS)) {
            // 查询企业名称
            enterpriseInfoQuery.tranEntInfoField(teamMemberVOS, new String[]{TeamEnterpriseVO.PK_ENTERPRISE},
                    new String[]{TeamEnterpriseVO.ENTERPRISE_NAME});
            // 因为项目经理是特殊角色，很难去判断属于哪一方，所以不通过用户角色去判断是否施工方，而是通过用户的企业角色判断是否施工方
            // 和需求沟通因为现在问题记录整改人没有做限制，不一样指定给施工方，所以暂时先不做角色限制，先注释掉
//            Set<String> enterpriseIdSet = new HashSet<>();
//            for (TeamMemberVO memberVO : teamMemberVOS) {
//                enterpriseIdSet.add(memberVO.getPkEnterprise());
//            }
//            TeamEnterpriseVO[] enterpriseVOS = query.queryTeamEnterpriseById(enterpriseIdSet.toArray(new String[0]));
//            Map<String, Byte> enterpriseRoleMap = new HashMap<>();
//            for (TeamEnterpriseVO enterpriseVO : enterpriseVOS) {
//                enterpriseRoleMap.put(enterpriseVO.getPkEnterprise() + enterpriseVO.getPkProject(), enterpriseVO.getEntRole());
//            }
            for (TeamMemberVO memberVO : teamMemberVOS) {
//                String entKey = memberVO.getPkEnterprise() + memberVO.getPkProject();
//                int entRole = enterpriseRoleMap.get(entKey) == null ? 0 :
//                        enterpriseRoleMap.get(entKey);
//                if (TeamEnterpriseVO.EnterpriseRoleConst.ROLE_CONSTRUCTOR == entRole) {
                    userIdMap.put(memberVO.getPkUser() + memberVO.getPkProject(), memberVO.getEnterpriseName());
                    userAndPkEntMap.put(memberVO.getPkUser() + memberVO.getPkProject(), memberVO.getPkEnterprise());
//                }
            }
        }
        // 以整改人主键组装问题记录
        Map<String, List<ProblemLogVO>> userLogMap = new HashMap<>();
        for (ProblemLogVO logVO : problemLogVOList) {
            String key = logVO.getPk_rectificationer() + logVO.getPk_project();
            if (userLogMap.get(key) == null) {
                userLogMap.put(key, new ArrayList<ProblemLogVO>());
            }
            userLogMap.get(key).add(logVO);
        }
        List<ProblemReasonPercentageVO> percentageVOList = new ArrayList<>();

        Map<String, ProblemReasonPercentageVO> enterpriseMap = new HashMap<>();
        for (Map.Entry<String, List<ProblemLogVO>> entry : userLogMap.entrySet()) {
            String enterpriseName = userIdMap.get(entry.getKey());
            String pkEnt = userAndPkEntMap.get(entry.getKey());
            List<ProblemLogVO> problemLogVOS = entry.getValue();
            int overdueCount = 0;
            for (ProblemLogVO logVO : problemLogVOS) {
                // 整改日期不填则不判断超期
                if(logVO.getEnddate() != null) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    String endDateStr = simpleDateFormat.format(logVO.getEnddate()) + " 23:59:59";
                    Date endDate;
                    try {
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        endDate = dateFormat.parse(endDateStr);
                    }catch (ParseException e){
                        throw new BusinessException("parse date :" + e.getMessage());
                    }
                    if (endDate != null && endDate.before(Calendar.getInstance().getTime())) {
                        overdueCount++;
                    }
                }
            }
            if (enterpriseMap.get(pkEnt) != null) {
                ProblemReasonPercentageVO reasonPercentageVO = enterpriseMap.get(pkEnt);
                reasonPercentageVO.setTotalCount(reasonPercentageVO.getTotalCount() + problemLogVOS.size());
                reasonPercentageVO.setOverdueCount(reasonPercentageVO.getOverdueCount() + overdueCount);
            } else {
                ProblemReasonPercentageVO percentageVO = new ProblemReasonPercentageVO();
                percentageVO.setTotalCount(problemLogVOS.size());
                percentageVO.setEnterpriseName(enterpriseName);
                percentageVO.setPkEnterprise(pkEnt);
                percentageVO.setOverdueCount(overdueCount);
                enterpriseMap.put(pkEnt, percentageVO);
            }
        }

        for (Map.Entry<String, ProblemReasonPercentageVO> entry : enterpriseMap.entrySet()) {
            percentageVOList.add(entry.getValue());
        }

        SortListUtil.sort(percentageVOList, "totalCount", "desc");
        // 最多显示5个
        int loopCount = 0;
        List<ProblemReasonPercentageVO> resultList = new ArrayList<>();
        for (ProblemReasonPercentageVO percentageVO : percentageVOList) {
            if (loopCount > 4) {
                break;
            }
            resultList.add(percentageVO);
            loopCount++;
        }
        return resultList.toArray(new ProblemReasonPercentageVO[0]);
    }

    /**
     * web质量多发分析-问题多发分析报表穿透，通过时间范围和问题原因名查询
     * @param problemName 问题原因名
     * @param range       时间范围
     * @param tenantId    租户
     * @return 问题报表VO数组
     * @throws BusinessException
     */
    @GetMapping("/queryProReportByRangeAndReason")
    public ProblemReportVO[] queryProblemReportByRangeAndReason(@RequestParam(value = "problemName[]") String[] problemName,
                                                                @RequestParam("range") String range,
                                                                @RequestParam("tenantId") String tenantId,
                                                                @RequestParam(value = "orgId", required = false) String orgId) throws BusinessException {
        // FIXME 问题记录过多的时候，可能会导致oom
        // 通过问题原因和时间范围查询所有的问题记录
        List<ProblemLogVO> results = query.queryProblemLogByTimeAndReason(tenantId, problemName, range, orgId);
        if (results == null || results.size() == 0)
            return null;
        Set<String> rectificationerIdSet = new HashSet<>();
        String pkRectificationer = null;
        for (ProblemLogVO problemLogVO : results) {
            pkRectificationer = problemLogVO.getPk_rectificationer();
            if (!StringUtils.isEmpty(pkRectificationer)) {
                rectificationerIdSet.add(pkRectificationer);
            }
        }
        if (rectificationerIdSet == null || rectificationerIdSet.size() == 0)
            return null;
        // 通过整改人主键在项目团队中找出对应的企业
        TeamMemberVO[] teamMemberVOS = query.queryTeamMemberById(rectificationerIdSet.toArray(new String[rectificationerIdSet.size()]));
        Map<String, String> userIdMap = queryEnterpriseName(teamMemberVOS);
        List<ProblemReportVO> reportVOs = query.queryProblemReportByRangeAndReason(tenantId, problemName, range, userIdMap, orgId);
        // 查询整改人姓名
        if (reportVOs == null || reportVOs.size() == 0)
            return null;
        ProblemReportVO[] reportArray = reportVOs.toArray(new ProblemReportVO[reportVOs.size()]);
        userInfoQuery.tranUserInfoField(reportArray, new String[]{ProblemReportVO.PK_RECTIFICATIONER}, new String[]{ProblemReportVO.RECTIFICATIONER_NAME});
        return reportArray;
    }

    /**
     * web统计分析未关闭问题报表穿透，通过施工单位和是否超期来查询
     * @param tenantId
     * @param enterpriseName
     * @param overdue
     * @return
     * @throws BusinessException
     */
    @GetMapping("/queryProblemReportByEntAndOverdue")
    public ProblemReportVO[] queryProblemReportByEntAndOverdue(@RequestParam("tenantId") String tenantId,
                                                               @RequestParam("pkEnterprise") String pkEnterprise,
                                                               @RequestParam("enterpriseName") String enterpriseName,
                                                               @RequestParam(value = "overdue", defaultValue = ProblemReportVO.PROBLEM_ALL + "") String overdue,
                                                               @RequestParam(value = "orgId") String orgId) throws BusinessException {
        byte isOverdue = Byte.parseByte(overdue);
        if (isOverdue != ProblemReportVO.PROBLEM_NOT_OVERDUE && isOverdue != ProblemReportVO.PROBLEM_OVERDUE && isOverdue != ProblemReportVO.PROBLEM_ALL) {
            throw new BusinessException("是否超期传参错误，请检查！");
        }
        List<ProblemReportVO> reportVOs = query.queryProblemReportByEntAndOverdue(tenantId, pkEnterprise, enterpriseName, isOverdue, orgId);
        // 查询整改人姓名
        ProblemReportVO[] reportArray = reportVOs.toArray(new ProblemReportVO[reportVOs.size()]);
        userInfoQuery.tranUserInfoField(reportArray, new String[]{ProblemReportVO.PK_RECTIFICATIONER}, new String[]{ProblemReportVO.RECTIFICATIONER_NAME});
        return reportArray;
    }

    /**
     * 查询企业名称
     *
     * @param teamMemberVOS
     * @return map，key是整改人+项目，value是企业名
     */
    private Map<String, String> queryEnterpriseName(TeamMemberVO[] teamMemberVOS) {
        Map<String, String> result = new HashMap<>();
        if (ArrayUtils.isNotEmpty(teamMemberVOS)) {
            // 查询企业名称
            enterpriseInfoQuery.tranEntInfoField(teamMemberVOS, new String[]{TeamEnterpriseVO.PK_ENTERPRISE},
                    new String[]{TeamEnterpriseVO.ENTERPRISE_NAME});
            for (TeamMemberVO memberVO : teamMemberVOS) {
                result.put(memberVO.getPkUser() + memberVO.getPkProject(), memberVO.getEnterpriseName());
            }
        }

        return result;
    }

}
